package zent

import (
	"fmt"
	"log"
	"net"
	"studygo/sp/a/zinx/utils"
	"studygo/sp/a/zinx/ziface"
)

//IServer 的接口实现，
type Server struct {
	//服务器名称
	Name string
	//服务器绑定的Ip版本
	IPversin string
	IP       string
	//服务器监听的端口
	Port int

	//当前server 添加 router.
	//Router ziface.IRouter

	//当前 server 的消息管理模块，用来绑定MsgId和对应业务API关系
	MsgHandler ziface.IMsgHandle
}

func (s *Server) AddRouter(msgId uint32, router ziface.IRouter) {
	//s.Router = router
	s.MsgHandler.AddRouter(msgId, router)
	log.Println("Add router succeccful!")
}

//定义当前客户端所绑定的API
/*func CallBackToClient(conn *net.TCPConn, buf []byte, cnt int) error {
	//回显业务
	log.Println("【Conn Handler CallBackToClient】")
	if _, err := conn.Write(buf[:cnt]); err != nil {
		log.Println("Write back buf err:", err)
		return errors.New("CallBackToClient err")
	}
	return nil
}*/
func (s *Server) Start() {
	log.Println("[zinx]", utils.GlocalObject)
	log.Println("[Start]Server Listenner ip:", s.IP, " port:", s.Port)

	go func() {
		addr, err := net.ResolveTCPAddr(s.IPversin, fmt.Sprintf("%s:%d", s.IP, s.Port))
		if err != nil {
			log.Panicln("服务器启动错误,err:", err)
			return
		}
		listener, err := net.ListenTCP(s.IPversin, addr)
		if err != nil {
			log.Println("listen err", err)
			return
		}

		log.Println("Start Zinx server successful")
		var cid uint32

		for {
			conn, err := listener.AcceptTCP()
			if err != nil {
				log.Println("listener.AcceptTCP:", err)
				continue
			}
			//回显给 客户端,最大512 字节

			//处理新链接的业务方法和conn绑定，得到我们的链接模块
			dealConn := NewConnection(conn, cid, s.MsgHandler)
			cid++
			//启动当前的链接业务
			go dealConn.Start()
		}
	}()
}

func (s *Server) Stop() {
	//TODO 将开辟的资源关闭或回收
}

func (s *Server) Server() {
	s.Start()

	//启动服务器之后做一些额外的业务
	//阻塞
	select {}
}

/**
初始化server模块
*/
func NewServer(name string) (server ziface.IServer) {
	server = &Server{
		Name:     utils.GlocalObject.Name,
		IPversin: "tcp4",
		IP:       utils.GlocalObject.Host,
		Port:     utils.GlocalObject.TcpPort,
		//Router:   nil,
		MsgHandler: NewMsgHandler(),
	}
	return server
}
